/**
 * 事件管理器
 */
export default class EventManager {
    private _events: Object = null;
    private static _instance: EventManager;
    constructor() {
        this._events = {};
    }
    public static get Inst(): EventManager {
        if (!this._instance) this._instance = new EventManager();
        return this._instance;
    }
    private addListener(type: string, thisObj: Object, callBack: Function, once: boolean) {
        if (!type) return cc.error("error type!!");
        if (!this._events[type]) {
            this._events[type] = [];
        }
        //重复添加
        let len = this._events[type].length;
        if (len) {
            for (let i = 0; i < len; i++) {
                let event = this._events[type][i];
                if (event.thisObj === thisObj && callBack === callBack) return;
            }
        }
        this._events[type].push({ thisObj: thisObj, callBack: callBack, once: once });
        // console.log("add " + type + " success:" + this._events[type].length);
    }
    /**添加事件--all */
    public on(type: string, thisObj: Object, callBack: Function|any) {
        this.addListener(type, thisObj, callBack, false);
    }
    /**添加事件--once */
    public once(type: string, thisObj: Object, callBack: Function) {
        this.addListener(type, thisObj, callBack, true);
    }
    /**派发事件 */
    public emit(type: string, data?: any, ...args: any) {
        if (!type) return cc.error("error type!!");
        let events = this._events[type];
        if (events) {
            for (let i = 0; i < events.length; i++) {
                let event = events[i];
                let callBack: Function = event.callBack;
                callBack.call(event.thisObj, data, args);
                if (event.once) {
                    events.splice(i, 1);
                    i--;
                }
            }
        }
    }
    /**
     * 移除事件
     * @param type 事件类型
     * @param thisObj 事件目标
     * @param callBack 事件回调
     *  */
    public off(type: string, thisObj: Object, callBack: Function) {
        if (!type || !thisObj || !callBack) return cc.error("error param!!");
        let events = this._events[type];
        //移除
        for (let i = 0, len = events.length; i < len; i++) {
            let event = this._events[type][i];
            if (event.thisObj === thisObj && callBack === callBack) {
                this._events[type].splice(i, 1);
                break;
            };
        }
        // console.log("off " + type + " success:" + this._events[type].length);
    }
    /**
     * 清除thisObj对象上的所有事件
     * @param thisObj 移除目标对象
     *  */
    public offAll(thisObj: Object) {
        if (!thisObj) return cc.error("error thisObj!!");
        // console.log("start off " + thisObj["name"]);
        for (let key in this._events) {
            if (this._events.hasOwnProperty(key)) {
                let events = this._events[key];
                for (let i = 0; i < events.length; i++) {
                    if (events[i].thisObj == thisObj) {
                        // console.log("off key:" + key);
                        events.splice(i, 1);
                        i--;
                    }
                }

                if (!events.length) {
                    delete this._events[key];
                }
            }
        }
        console.log("off " + thisObj["name"] + " success!!!");
    }
    /**
     * 清除某一类型的监听事件
     * @param type 事件类型
     */
    public offType(type: string) {
        if (!type) return cc.error("error type !!");
        delete this._events[type];
    }
}
